#include "system.h"
using std::runtime_error;
using sys::runtime_error_ex;
using sys::system_error;


void sys::RegistryKey::Init(const HKEY parentKey,
					     const char * path)
{
	if (RegCreateKey(parentKey,path,&_hkey) != ERROR_SUCCESS)
		throw runtime_error("RegCreateKey failed");
	
}
sys::RegistryKey::RegistryKey(const HKEY parentKey,
					     const char * path)
{
	Init(parentKey,path);
}

sys::RegistryKey::RegistryKey(const char * path)
{
	Init(HKEY_CURRENT_USER,path);
}

sys::RegistryKey::~RegistryKey()
{
}

void sys::RegistryKey::GetValue(const char * entry_name,
							DWORD &type, BYTE * buffer, DWORD size)
{
	const LONG result =
 		RegQueryValueEx(_hkey,entry_name,NULL,&type,buffer,&size);
	if (result == 2) // file not found
	{
		type = REG_NONE;
		*buffer = 0;
		return;
	}
	if (result != ERROR_SUCCESS)
		throw system_error(result);
}

void sys::RegistryKey::SetValue(const char * entry_name,
							DWORD type, const BYTE * buffer, DWORD size)
{
	if (RegSetValueEx(_hkey,entry_name,0,type,buffer,size)
			!= ERROR_SUCCESS)
		throw runtime_error("RegSetValueEx failed");
}

int sys::RegistryKey::GetIntValue(const char * entry_name)
{
	DWORD type;
	DWORD result;
	GetValue(entry_name,type,(BYTE*)&result,(DWORD)sizeof(result));
	if (type == REG_NONE)
		return 0;
	if (type != REG_DWORD)
		throw runtime_error_ex("Expected an integer value  for %s in registry",
  						entry_name);
	return result;
}

void sys::RegistryKey::SetValue(const char * entry_name, const int value)
{
	DWORD v = value;
 	SetValue(entry_name,REG_DWORD,(BYTE*)&v,sizeof(v));
}

void sys::RegistryKey::GetValue(const char * entry_name, 
   					char * result, const int size)
{
	DWORD type;
	GetValue(entry_name,type,(BYTE*)result,size);
	if (type == REG_NONE)
		*result = '\0';
	else if (type != REG_SZ)
 		throw runtime_error_ex("Expected a string value  for %s in registry",
  						entry_name);
}

void sys::RegistryKey::SetValue(const char * entry_name, const char * value)
{
 	SetValue(entry_name,REG_SZ,(BYTE*)value,strlen(value)+1);
}

